﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using TaDMS.Models;

namespace TaDMS.Controllers
{
    [Authorize(Roles = "Admin, TruongPhong, PhoPhong, Editer")]
    public class ApiDeviceController : ApiController
    {
        private readonly UnitOfWork _unitOfWork = new UnitOfWork();

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetAll(int start, int limit, int categoryId)
        {
            int? total;
            var devices = _unitOfWork.DeviceRepository.GetData(out total, orderBy: order => order.OrderBy(v => v.Serial), isPaging: true, start: start, limit: limit, includeProperties: "Department,Distributor,Project,DeviceCategory", filter: v => v.DeviceCategoryId == categoryId);

            if (devices != null && String.IsNullOrEmpty(_unitOfWork.DeviceRepository.ErrorMessage))
            {
                if (total > 0)
                {
                    var result = new
                    {
                        total = total,
                        success = true,
                        message = "success",
                        data = devices.ToList()
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }

                var empty = new
                {
                    success = true,
                    message = "Devices is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }
            else
            {
                var error = new
                {
                    success = false,
                    message = _unitOfWork.DeviceRepository.ErrorMessage
                };
                return Request.CreateResponse(HttpStatusCode.OK, error);
            }
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetAll(int start, int limit, string serial, string deviceName, string deviceStatus, string deviceCategory, 
                                          DateTime? dateOfPurchase, DateTime? dateOfPurchaseFrom, DateTime? dateOfPurchaseTo, int? monthWarranty, 
                                          string department, string distributor, string project, string manufacturer)
        {

            var filterExpressions = new List<Expression<Func<Device, bool>>>();
            if (serial != null && !String.IsNullOrWhiteSpace(serial))
            {
                Expression<Func<Device, bool>> expression = device => device.Serial.Contains(serial);
                filterExpressions.Add(expression);
            }
            if (deviceStatus != null && !String.IsNullOrWhiteSpace(deviceStatus))
            {
                Expression<Func<Device, bool>> expression = device => device.DeviceStatus.Contains(deviceStatus);
                filterExpressions.Add(expression);
            }
            if (deviceName != null && !String.IsNullOrWhiteSpace(deviceName))
            {
                Expression<Func<Device, bool>> expression = device => device.DeviceName.Contains(deviceName);
                filterExpressions.Add(expression);
            }
            if (deviceCategory != null && !String.IsNullOrWhiteSpace(deviceCategory))
            {
                Expression<Func<Device, bool>> expression = device => device.DeviceCategory.Name.Contains(deviceCategory);
                filterExpressions.Add(expression);
            }
            if (dateOfPurchase != null)
            {
                Expression<Func<Device, bool>> expression = device => device.DateOfPurchase == dateOfPurchase;
                filterExpressions.Add(expression);
            }
            if (dateOfPurchase == null && dateOfPurchaseFrom != null && dateOfPurchaseTo != null )
            {
                Expression<Func<Device, bool>> expression = device => device.DateOfPurchase >= dateOfPurchaseFrom && device.DateOfPurchase <= dateOfPurchaseTo;
                filterExpressions.Add(expression);
            }
            if (monthWarranty != null)
            {
                Expression<Func<Device, bool>> expression = device => device.MonthWarranty == monthWarranty;
                filterExpressions.Add(expression);
            }
            if (department != null && !String.IsNullOrWhiteSpace(department))
            {
                Expression<Func<Device, bool>> expression = device => device.Department.DepartmentName.Contains(department);
                filterExpressions.Add(expression);
            }
            if (distributor != null && !String.IsNullOrWhiteSpace(distributor))
            {
                Expression<Func<Device, bool>> expression = device => device.Distributor.Name.Contains(distributor);
                filterExpressions.Add(expression);
            }
            if (project != null && !String.IsNullOrWhiteSpace(project))
            {
                Expression<Func<Device, bool>> expression = device => device.Project.Name.Contains(project);
                filterExpressions.Add(expression);
            }
            if (manufacturer != null && !String.IsNullOrWhiteSpace(manufacturer))
            {
                Expression<Func<Device, bool>> expression = device => device.Manufacturer.Contains(manufacturer);
                filterExpressions.Add(expression);
            }

            int? total;
            var devices = _unitOfWork.Device.GetData(out total, orderBy: o => o.OrderBy(v => v.Serial), multiFilter: filterExpressions, isPaging: true, start: start, limit: limit, includeProperties: "Department,Distributor,Project,DeviceCategory");

            if (devices != null && String.IsNullOrEmpty(_unitOfWork.DeviceRepository.ErrorMessage))
            {
                if (total > 0)
                {
                    var result = new
                    {
                        total = total,
                        success = true,
                        message = "success",
                        data = devices.ToList()
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }

                var empty = new
                {
                    success = true,
                    message = "Devices is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }
            else
            {
                var error = new
                {
                    success = false,
                    message = _unitOfWork.DeviceRepository.ErrorMessage
                };
                return Request.CreateResponse(HttpStatusCode.OK, error);
            }
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetDepartmentComboData(int start, int limit, string query)
        {
            int? total;
            var result = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.Department.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DepartmentName)) :
                _unitOfWork.Department.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DepartmentName), filter: d => d.DepartmentName.ToUpper().Contains(query.Trim().ToUpper()));
            
            if (result != null && String.IsNullOrEmpty(_unitOfWork.Department.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = result.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Department.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetProjectComboData(int start, int limit, string query)
        {
            int? total;
            var result = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.ProjectRepository.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name)) :
                _unitOfWork.ProjectRepository.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name), filter: d => d.Name.ToUpper().Contains(query.Trim().ToUpper()));

            if (result != null && String.IsNullOrEmpty(_unitOfWork.ProjectRepository.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = result.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.ProjectRepository.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetDistributorComboData(int start, int limit, string query)
        {
            int? total;
            var result = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.DistributorRepository.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name)) :
                _unitOfWork.DistributorRepository.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name), filter: d => d.Name.ToUpper().Contains(query.Trim().ToUpper()));

            if (result != null && String.IsNullOrEmpty(_unitOfWork.DistributorRepository.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = result.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.DistributorRepository.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetManufacturerComboData(int start, int limit, string query)
        {
            int? total;
            var result = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Manufacturer)).Where(v => v.Manufacturer != null && !String.IsNullOrEmpty(v.Manufacturer)).Select(v => new { Manufacture = v.Manufacturer }).Distinct() :
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Manufacturer), filter: d => !String.IsNullOrEmpty(d.Manufacturer) && d.Manufacturer.ToUpper().Contains(query.Trim().ToUpper())).Select(v => new { Manufacture = v.Manufacturer }).Distinct();

            if (String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = result.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetSerialComboData(int start, int limit, string query)
        {
            int? total;
            var results = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Serial)).Where(v => v.Serial != null && !String.IsNullOrEmpty(v.Serial)).Select(v => new { Serial = v.Serial }).Distinct() :
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Serial), filter: d => d.Serial.ToUpper().Contains(query.Trim().ToUpper())).Select(v => new { Serial = v.Serial }).Distinct();

            if (String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = results.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetDeviceNameComboData(int start, int limit, string query)
        {
            int? total;
            var results = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DeviceName)).Where(v => v.DeviceName != null && !String.IsNullOrEmpty(v.DeviceName)).Select(v => new { DeviceName = v.DeviceName }).Distinct() :
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DeviceName), filter: d => !String.IsNullOrEmpty(d.DeviceName) && d.DeviceName.ToUpper().Contains(query.Trim().ToUpper())).Select(v => new { DeviceName = v.DeviceName }).Distinct();

            if (String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = results.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetDeviceStatusComboData(int start, int limit, string query)
        {
            int? total;
            var results = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DeviceStatus)).Where(v => v.DeviceStatus != null && !String.IsNullOrEmpty(v.DeviceStatus)).Select(v => new { DeviceStatus = v.DeviceStatus }).Distinct() :
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.DeviceStatus), filter: d => !String.IsNullOrEmpty(d.DeviceStatus) && d.DeviceStatus.ToUpper().Contains(query.Trim().ToUpper())).Select(v => new { DeviceStatus = v.DeviceStatus }).Distinct();

            if (String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = results.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetMonthWarrantyComboData(int start, int limit, int? query)
        {
            int? total;
            var results = query == null ?
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.MonthWarranty)).Where(v => v.MonthWarranty != null).Select(v => new { MonthWarranty = v.MonthWarranty }).Distinct() :
                _unitOfWork.Device.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.MonthWarranty), filter: d => d.MonthWarranty != null && d.MonthWarranty == query).Select(v => new { MonthWarranty = v.MonthWarranty }).Distinct();

            if (String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = results.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpGet]
        public HttpResponseMessage GetCategoryComboData(int start, int limit, string query)
        {
            int? total;
            var result = String.IsNullOrEmpty(query) || query.Trim().ToUpper().Equals("ALL") ?
                _unitOfWork.DeviceCategory.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name)) :
                _unitOfWork.DeviceCategory.GetData(total: out total, isPaging: true, start: start, limit: limit, orderBy: order => order.OrderBy(d => d.Name), filter: d => d.Name.ToUpper().Contains(query.Trim().ToUpper()));

            if (result != null && String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                if (total > 0)
                {
                    var success = new
                    {
                        total = total,
                        success = true,
                        data = result.ToList(),
                        message = "success"
                    };
                    return Request.CreateResponse(HttpStatusCode.OK, success);
                }

                var empty = new
                {
                    total = 0,
                    success = true,
                    message = "data is empty"
                };
                return Request.CreateResponse(HttpStatusCode.OK, empty);
            }

            var error = new
            {
                success = false,
                message = "False. " + _unitOfWork.Device.ErrorMessage
            };
            return Request.CreateResponse(HttpStatusCode.OK, error);
        }

        [System.Web.Http.HttpPost]
        public HttpResponseMessage Create(Device entity)
        {
            var result = _unitOfWork.Device.Create(entity);

            if (result != null && String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                var success = new
                {
                    data = result,
                    success = true,
                    message = "Created"
                };
                return Request.CreateResponse(HttpStatusCode.OK, success);
            }
            else
            {
                var error = new
                {
                    success = false,
                    message = "Craete false: " + _unitOfWork.Device.ErrorMessage
                };
                return Request.CreateResponse(HttpStatusCode.OK, error);
            }
        }

        [System.Web.Http.HttpPost]
        public HttpResponseMessage Update(Device entity, string fields)
        {
            var result = _unitOfWork.Device.Update(entity, fields);

            if (result != null && String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                var success = new
                {
                    data = result,
                    success = true,
                    message = "Updated"
                };
                return Request.CreateResponse(HttpStatusCode.OK, success);
            }
            else
            {
                var error = new
                {
                    success = false,
                    message = "Update false: " + _unitOfWork.Device.ErrorMessage
                };
                return Request.CreateResponse(HttpStatusCode.OK, error);
            }
        }

        [System.Web.Http.HttpPost]
        public HttpResponseMessage Delete(Device entity)
        {
            var result = _unitOfWork.Device.Delete(entity);

            if (result != null && String.IsNullOrEmpty(_unitOfWork.Device.ErrorMessage))
            {
                var success = new
                {
                    data = result,
                    success = true,
                    message = "Deleted"
                };
                return Request.CreateResponse(HttpStatusCode.OK, success);
            }
            else
            {
                var error = new
                {
                    success = false,
                    message = "Delete false: " + _unitOfWork.Device.ErrorMessage
                };
                return Request.CreateResponse(HttpStatusCode.OK, error);
            }
        }
    }
}
